home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / RCS / savemail.c,v < prev    next >
Encoding:
Text File  |  1991-06-25  |  22.0 KB  |  1,083 lines

  1. head    5.13;
  2. branch    5.13.0;
  3. access;
  4. symbols
  5.     RELEASE:5.13.0.15
  6.     BETA:5.13.0.14
  7.     UICSO:5.13.0
  8.     VANILLA:5.13;
  9. locks; strict;
  10. comment    @ * @;
  11.  
  12.  
  13. 5.13
  14. date    90.06.20.08.36.24;    author paul;    state Exp;
  15. branches
  16.     5.13.0.1;
  17. next    ;
  18.  
  19. 5.13.0.1
  20. date    90.06.20.09.43.57;    author paul;    state Exp;
  21. branches;
  22. next    5.13.0.2;
  23.  
  24. 5.13.0.2
  25. date    90.06.20.13.58.01;    author paul;    state Exp;
  26. branches;
  27. next    5.13.0.3;
  28.  
  29. 5.13.0.3
  30. date    90.07.20.16.05.37;    author paul;    state Exp;
  31. branches;
  32. next    5.13.0.4;
  33.  
  34. 5.13.0.4
  35. date    90.08.27.16.49.46;    author paul;    state Exp;
  36. branches;
  37. next    5.13.0.5;
  38.  
  39. 5.13.0.5
  40. date    90.10.02.00.44.06;    author paul;    state Exp;
  41. branches;
  42. next    5.13.0.6;
  43.  
  44. 5.13.0.6
  45. date    90.10.13.19.10.23;    author paul;    state Exp;
  46. branches;
  47. next    5.13.0.7;
  48.  
  49. 5.13.0.7
  50. date    90.11.24.21.54.57;    author paul;    state Exp;
  51. branches;
  52. next    5.13.0.8;
  53.  
  54. 5.13.0.8
  55. date    91.01.19.19.26.02;    author paul;    state Exp;
  56. branches;
  57. next    5.13.0.9;
  58.  
  59. 5.13.0.9
  60. date    91.02.17.05.16.13;    author paul;    state Exp;
  61. branches;
  62. next    5.13.0.10;
  63.  
  64. 5.13.0.10
  65. date    91.03.04.21.48.23;    author paul;    state Exp;
  66. branches;
  67. next    5.13.0.11;
  68.  
  69. 5.13.0.11
  70. date    91.03.05.16.42.59;    author paul;    state Exp;
  71. branches;
  72. next    5.13.0.12;
  73.  
  74. 5.13.0.12
  75. date    91.03.06.15.13.33;    author paul;    state Exp;
  76. branches;
  77. next    5.13.0.13;
  78.  
  79. 5.13.0.13
  80. date    91.04.05.14.55.15;    author paul;    state Exp;
  81. branches;
  82. next    5.13.0.14;
  83.  
  84. 5.13.0.14
  85. date    91.05.18.18.18.55;    author paul;    state Exp;
  86. branches;
  87. next    5.13.0.15;
  88.  
  89. 5.13.0.15
  90. date    91.06.24.16.22.54;    author paul;    state Exp;
  91. branches;
  92. next    ;
  93.  
  94.  
  95. desc
  96. @@
  97.  
  98.  
  99. 5.13
  100. log
  101. @5.64 Berkeley release
  102. @
  103. text
  104. @/*
  105.  * Copyright (c) 1983 Eric P. Allman
  106.  * Copyright (c) 1988 Regents of the University of California.
  107.  * All rights reserved.
  108.  *
  109.  * Redistribution and use in source and binary forms are permitted provided
  110.  * that: (1) source distributions retain this entire copyright notice and
  111.  * comment, and (2) distributions including binaries display the following
  112.  * acknowledgement:  ``This product includes software developed by the
  113.  * University of California, Berkeley and its contributors'' in the
  114.  * documentation or other materials provided with the distribution and in
  115.  * all advertising materials mentioning features or use of this software.
  116.  * Neither the name of the University nor the names of its contributors may
  117.  * be used to endorse or promote products derived from this software without
  118.  * specific prior written permission.
  119.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  120.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  121.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  122.  */
  123.  
  124. #ifndef lint
  125. static char sccsid[] = "@@(#)savemail.c    5.13 (Berkeley) 6/1/90";
  126. #endif /* not lint */
  127.  
  128. # include <sys/types.h>
  129. # include <pwd.h>
  130. # include "sendmail.h"
  131.  
  132. /*
  133. **  SAVEMAIL -- Save mail on error
  134. **
  135. **    If mailing back errors, mail it back to the originator
  136. **    together with an error message; otherwise, just put it in
  137. **    dead.letter in the user's home directory (if he exists on
  138. **    this machine).
  139. **
  140. **    Parameters:
  141. **        e -- the envelope containing the message in error.
  142. **
  143. **    Returns:
  144. **        none
  145. **
  146. **    Side Effects:
  147. **        Saves the letter, by writing or mailing it back to the
  148. **        sender, or by putting it in dead.letter in her home
  149. **        directory.
  150. */
  151.  
  152. /* defines for state machine */
  153. # define ESM_REPORT    0    /* report to sender's terminal */
  154. # define ESM_MAIL    1    /* mail back to sender */
  155. # define ESM_QUIET    2    /* messages have already been returned */
  156. # define ESM_DEADLETTER    3    /* save in ~/dead.letter */
  157. # define ESM_POSTMASTER    4    /* return to postmaster */
  158. # define ESM_USRTMP    5    /* save in /usr/tmp/dead.letter */
  159. # define ESM_PANIC    6    /* leave the locked queue/transcript files */
  160. # define ESM_DONE    7    /* the message is successfully delivered */
  161.  
  162.  
  163. savemail(e)
  164.     register ENVELOPE *e;
  165. {
  166.     register struct passwd *pw;
  167.     register FILE *fp;
  168.     int state;
  169.     auto ADDRESS *q;
  170.     char buf[MAXLINE+1];
  171.     extern struct passwd *getpwnam();
  172.     register char *p;
  173.     extern char *ttypath();
  174.     typedef int (*fnptr)();
  175.  
  176.     if (tTd(6, 1))
  177.         printf("\nsavemail, ErrorMode = %c\n", ErrorMode);
  178.  
  179.     if (bitset(EF_RESPONSE, e->e_flags))
  180.         return;
  181.     if (e->e_class < 0)
  182.     {
  183.         message(Arpa_Info, "Dumping junk mail");
  184.         return;
  185.     }
  186.     ForceMail = TRUE;
  187.     e->e_flags &= ~EF_FATALERRS;
  188.  
  189.     /*
  190.     **  In the unhappy event we don't know who to return the mail
  191.     **  to, make someone up.
  192.     */
  193.  
  194.     if (e->e_from.q_paddr == NULL)
  195.     {
  196.         if (parseaddr("root", &e->e_from, 0, '\0') == NULL)
  197.         {
  198.             syserr("Cannot parse root!");
  199.             ExitStat = EX_SOFTWARE;
  200.             finis();
  201.         }
  202.     }
  203.     e->e_to = NULL;
  204.  
  205.     /*
  206.     **  Basic state machine.
  207.     **
  208.     **    This machine runs through the following states:
  209.     **
  210.     **    ESM_QUIET    Errors have already been printed iff the
  211.     **            sender is local.
  212.     **    ESM_REPORT    Report directly to the sender's terminal.
  213.     **    ESM_MAIL    Mail response to the sender.
  214.     **    ESM_DEADLETTER    Save response in ~/dead.letter.
  215.     **    ESM_POSTMASTER    Mail response to the postmaster.
  216.     **    ESM_PANIC    Save response anywhere possible.
  217.     */
  218.  
  219.     /* determine starting state */
  220.     switch (ErrorMode)
  221.     {
  222.       case EM_WRITE:
  223.         state = ESM_REPORT;
  224.         break;
  225.  
  226.       case EM_BERKNET:
  227.         /* mail back, but return o.k. exit status */
  228.         ExitStat = EX_OK;
  229.  
  230.         /* fall through.... */
  231.  
  232.       case EM_MAIL:
  233.         state = ESM_MAIL;
  234.         break;
  235.  
  236.       case EM_PRINT:
  237.       case '\0':
  238.         state = ESM_QUIET;
  239.         break;
  240.  
  241.       case EM_QUIET:
  242.         /* no need to return anything at all */
  243.         return;
  244.  
  245.       default:
  246.         syserr("savemail: ErrorMode x%x\n");
  247.         state = ESM_MAIL;
  248.         break;
  249.     }
  250.  
  251.     while (state != ESM_DONE)
  252.     {
  253.         if (tTd(6, 5))
  254.             printf("  state %d\n", state);
  255.  
  256.         switch (state)
  257.         {
  258.           case ESM_QUIET:
  259.             if (e->e_from.q_mailer == LocalMailer)
  260.                 state = ESM_DEADLETTER;
  261.             else
  262.                 state = ESM_MAIL;
  263.             break;
  264.  
  265.           case ESM_REPORT:
  266.  
  267.             /*
  268.             **  If the user is still logged in on the same terminal,
  269.             **  then write the error messages back to hir (sic).
  270.             */
  271.  
  272.             p = ttypath();
  273.             if (p == NULL || freopen(p, "w", stdout) == NULL)
  274.             {
  275.                 state = ESM_MAIL;
  276.                 break;
  277.             }
  278.  
  279.             expand("\001n", buf, &buf[sizeof buf - 1], e);
  280.             printf("\r\nMessage from %s...\r\n", buf);
  281.             printf("Errors occurred while sending mail.\r\n");
  282.             if (e->e_xfp != NULL)
  283.             {
  284.                 (void) fflush(e->e_xfp);
  285.                 fp = fopen(queuename(e, 'x'), "r");
  286.             }
  287.             else
  288.                 fp = NULL;
  289.             if (fp == NULL)
  290.             {
  291.                 syserr("Cannot open %s", queuename(e, 'x'));
  292.                 printf("Transcript of session is unavailable.\r\n");
  293.             }
  294.             else
  295.             {
  296.                 printf("Transcript follows:\r\n");
  297.                 while (fgets(buf, sizeof buf, fp) != NULL &&
  298.                        !ferror(stdout))
  299.                     fputs(buf, stdout);
  300.                 (void) fclose(fp);
  301.             }
  302.             printf("Original message will be saved in dead.letter.\r\n");
  303.             state = ESM_DEADLETTER;
  304.             break;
  305.  
  306.           case ESM_MAIL:
  307.           case ESM_POSTMASTER:
  308.             /*
  309.             **  If mailing back, do it.
  310.             **    Throw away all further output.  Don't alias,
  311.             **    since this could cause loops, e.g., if joe
  312.             **    mails to joe@@x, and for some reason the network
  313.             **    for @@x is down, then the response gets sent to
  314.             **    joe@@x, which gives a response, etc.  Also force
  315.             **    the mail to be delivered even if a version of
  316.             **    it has already been sent to the sender.
  317.             */
  318.  
  319.             if (state == ESM_MAIL)
  320.             {
  321.                 if (e->e_errorqueue == NULL)
  322.                     sendtolist(e->e_from.q_paddr,
  323.                         (ADDRESS *) NULL,
  324.                         &e->e_errorqueue);
  325.  
  326.                 /* deliver a cc: to the postmaster if desired */
  327.                 if (PostMasterCopy != NULL)
  328.                     sendtolist(PostMasterCopy,
  329.                         (ADDRESS *) NULL,
  330.                         &e->e_errorqueue);
  331.                 q = e->e_errorqueue;
  332.             }
  333.             else
  334.             {
  335.                 if (parseaddr("postmaster", q, 0, '\0') == NULL)
  336.                 {
  337.                     syserr("cannot parse postmaster!");
  338.                     ExitStat = EX_SOFTWARE;
  339.                     state = ESM_USRTMP;
  340.                     break;
  341.                 }
  342.             }
  343.             if (returntosender(e->e_message != NULL ? e->e_message :
  344.                        "Unable to deliver mail",
  345.                        q, TRUE) == 0)
  346.             {
  347.                 state = ESM_DONE;
  348.                 break;
  349.             }
  350.  
  351.             state = state == ESM_MAIL ? ESM_POSTMASTER : ESM_USRTMP;
  352.             break;
  353.  
  354.           case ESM_DEADLETTER:
  355.             /*
  356.             **  Save the message in dead.letter.
  357.             **    If we weren't mailing back, and the user is
  358.             **    local, we should save the message in
  359.             **    ~/dead.letter so that the poor person doesn't
  360.             **    have to type it over again -- and we all know
  361.             **    what poor typists UNIX users are.
  362.             */
  363.  
  364.             p = NULL;
  365.             if (e->e_from.q_mailer == LocalMailer)
  366.             {
  367.                 if (e->e_from.q_home != NULL)
  368.                     p = e->e_from.q_home;
  369.                 else if ((pw = getpwnam(e->e_from.q_user)) != NULL)
  370.                     p = pw->pw_dir;
  371.             }
  372.             if (p == NULL)
  373.             {
  374.                 syserr("Can't return mail to %s", e->e_from.q_paddr);
  375.                 state = ESM_MAIL;
  376.                 break;
  377.             }
  378.             if (e->e_dfp != NULL)
  379.             {
  380.                 auto ADDRESS *q;
  381.                 bool oldverb = Verbose;
  382.  
  383.                 /* we have a home directory; open dead.letter */
  384.                 define('z', p, e);
  385.                 expand("\001z/dead.letter", buf, &buf[sizeof buf - 1], e);
  386.                 Verbose = TRUE;
  387.                 message(Arpa_Info, "Saving message in %s", buf);
  388.                 Verbose = oldverb;
  389.                 e->e_to = buf;
  390.                 q = NULL;
  391.                 sendtolist(buf, (ADDRESS *) NULL, &q);
  392.                 if (deliver(e, q) == 0)
  393.                     state = ESM_DONE;
  394.                 else
  395.                     state = ESM_MAIL;
  396.             }
  397.             else
  398.             {
  399.                 /* no data file -- try mailing back */
  400.                 state = ESM_MAIL;
  401.             }
  402.             break;
  403.  
  404.           case ESM_USRTMP:
  405.             /*
  406.             **  Log the mail in /usr/tmp/dead.letter.
  407.             */
  408.  
  409.             fp = dfopen("/usr/tmp/dead.letter", "a");
  410.             if (fp == NULL)
  411.             {
  412.                 state = ESM_PANIC;
  413.                 break;
  414.             }
  415.  
  416.             putfromline(fp, ProgMailer);
  417.             (*e->e_puthdr)(fp, ProgMailer, e);
  418.             putline("\n", fp, ProgMailer);
  419.             (*e->e_putbody)(fp, ProgMailer, e);
  420.             putline("\n", fp, ProgMailer);
  421.             (void) fflush(fp);
  422.             state = ferror(fp) ? ESM_PANIC : ESM_DONE;
  423.             (void) fclose(fp);
  424.             break;
  425.  
  426.           default:
  427.             syserr("savemail: unknown state %d", state);
  428.  
  429.             /* fall through ... */
  430.  
  431.           case ESM_PANIC:
  432.             syserr("savemail: HELP!!!!");
  433. # ifdef LOG
  434.             if (LogLevel >= 1)
  435.                 syslog(LOG_ALERT, "savemail: HELP!!!!");
  436. # endif LOG
  437.  
  438.             /* leave the locked queue & transcript files around */
  439.             exit(EX_SOFTWARE);
  440.         }
  441.     }
  442. }
  443. /*
  444. **  RETURNTOSENDER -- return a message to the sender with an error.
  445. **
  446. **    Parameters:
  447. **        msg -- the explanatory message.
  448. **        returnq -- the queue of people to send the message to.
  449. **        sendbody -- if TRUE, also send back the body of the
  450. **            message; otherwise just send the header.
  451. **
  452. **    Returns:
  453. **        zero -- if everything went ok.
  454. **        else -- some error.
  455. **
  456. **    Side Effects:
  457. **        Returns the current message to the sender via
  458. **        mail.
  459. */
  460.  
  461. static bool    SendBody;
  462.  
  463. #define MAXRETURNS    6    /* max depth of returning messages */
  464.  
  465. returntosender(msg, returnq, sendbody)
  466.     char *msg;
  467.     ADDRESS *returnq;
  468.     bool sendbody;
  469. {
  470.     char buf[MAXNAME];
  471.     extern putheader(), errbody();
  472.     register ENVELOPE *ee;
  473.     extern ENVELOPE *newenvelope();
  474.     ENVELOPE errenvelope;
  475.     static int returndepth;
  476.     register ADDRESS *q;
  477.  
  478.     if (tTd(6, 1))
  479.     {
  480.         printf("Return To Sender: msg=\"%s\", depth=%d, CurEnv=%x,\n",
  481.                msg, returndepth, CurEnv);
  482.         printf("\treturnq=");
  483.         printaddr(returnq, TRUE);
  484.     }
  485.  
  486.     if (++returndepth >= MAXRETURNS)
  487.     {
  488.         if (returndepth != MAXRETURNS)
  489.             syserr("returntosender: infinite recursion on %s", returnq->q_paddr);
  490.         /* don't "unrecurse" and fake a clean exit */
  491.         /* returndepth--; */
  492.         return (0);
  493.     }
  494.  
  495.     SendBody = sendbody;
  496.     define('g', "\001f", CurEnv);
  497.     ee = newenvelope(&errenvelope);
  498.     define('a', "\001b", ee);
  499.     ee->e_puthdr = putheader;
  500.     ee->e_putbody = errbody;
  501.     ee->e_flags |= EF_RESPONSE;
  502.     ee->e_sendqueue = returnq;
  503.     openxscript(ee);
  504.     for (q = returnq; q != NULL; q = q->q_next)
  505.     {
  506.         if (q->q_alias == NULL)
  507.             addheader("to", q->q_paddr, ee);
  508.     }
  509.  
  510.     (void) sprintf(buf, "Returned mail: %s", msg);
  511.     addheader("subject", buf, ee);
  512.  
  513.     /* fake up an address header for the from person */
  514.     expand("\001n", buf, &buf[sizeof buf - 1], CurEnv);
  515.     if (parseaddr(buf, &ee->e_from, -1, '\0') == NULL)
  516.     {
  517.         syserr("Can't parse myself!");
  518.         ExitStat = EX_SOFTWARE;
  519.         returndepth--;
  520.         return (-1);
  521.     }
  522.     loweraddr(&ee->e_from);
  523.  
  524.     /* push state into submessage */
  525.     CurEnv = ee;
  526.     define('f', "\001n", ee);
  527.     define('x', "Mail Delivery Subsystem", ee);
  528.     eatheader(ee);
  529.  
  530.     /* actually deliver the error message */
  531.     sendall(ee, SM_DEFAULT);
  532.  
  533.     /* restore state */
  534.     dropenvelope(ee);
  535.     CurEnv = CurEnv->e_parent;
  536.     returndepth--;
  537.  
  538.     /* should check for delivery errors here */
  539.     return (0);
  540. }
  541. /*
  542. **  ERRBODY -- output the body of an error message.
  543. **
  544. **    Typically this is a copy of the transcript plus a copy of the
  545. **    original offending message.
  546. **
  547. **    Parameters:
  548. **        fp -- the output file.
  549. **        m -- the mailer to output to.
  550. **        e -- the envelope we are working in.
  551. **
  552. **    Returns:
  553. **        none
  554. **
  555. **    Side Effects:
  556. **        Outputs the body of an error message.
  557. */
  558.  
  559. errbody(fp, m, e)
  560.     register FILE *fp;
  561.     register struct mailer *m;
  562.     register ENVELOPE *e;
  563. {
  564.     register FILE *xfile;
  565.     char buf[MAXLINE];
  566.     char *p;
  567.  
  568.     /*
  569.     **  Output transcript of errors
  570.     */
  571.  
  572.     (void) fflush(stdout);
  573.     p = queuename(e->e_parent, 'x');
  574.     if ((xfile = fopen(p, "r")) == NULL)
  575.     {
  576.         syserr("Cannot open %s", p);
  577.         fprintf(fp, "  ----- Transcript of session is unavailable -----\n");
  578.     }
  579.     else
  580.     {
  581.         fprintf(fp, "   ----- Transcript of session follows -----\n");
  582.         if (e->e_xfp != NULL)
  583.             (void) fflush(e->e_xfp);
  584.         while (fgets(buf, sizeof buf, xfile) != NULL)
  585.             putline(buf, fp, m);
  586.         (void) fclose(xfile);
  587.     }
  588.     errno = 0;
  589.  
  590.     /*
  591.     **  Output text of original message
  592.     */
  593.  
  594.     if (NoReturn)
  595.         fprintf(fp, "\n   ----- Return message suppressed -----\n\n");
  596.     else if (e->e_parent->e_dfp != NULL)
  597.     {
  598.         if (SendBody)
  599.         {
  600.             putline("\n", fp, m);
  601.             putline("   ----- Unsent message follows -----\n", fp, m);
  602.             (void) fflush(fp);
  603.             putheader(fp, m, e->e_parent);
  604.             putline("\n", fp, m);
  605.             putbody(fp, m, e->e_parent);
  606.         }
  607.         else
  608.         {
  609.             putline("\n", fp, m);
  610.             putline("  ----- Message header follows -----\n", fp, m);
  611.             (void) fflush(fp);
  612.             putheader(fp, m, e->e_parent);
  613.         }
  614.     }
  615.     else
  616.     {
  617.         putline("\n", fp, m);
  618.         putline("  ----- No message was collected -----\n", fp, m);
  619.         putline("\n", fp, m);
  620.     }
  621.  
  622.     /*
  623.     **  Cleanup and exit
  624.     */
  625.  
  626.     if (errno != 0)
  627.         syserr("errbody: I/O error");
  628. }
  629. @
  630.  
  631.  
  632. 5.13.0.1
  633. log
  634. @IDA patches
  635. @
  636. text
  637. @d222 6
  638. d232 1
  639. a232 1
  640.                 if (PostMasterCopy != NULL)
  641. a233 32
  642.                     if ((q = parseaddr(PostMasterCopy,
  643.                                NULL, 0, '\0')) == NULL)
  644.                     {
  645.                     if (!strcasecmp("postmaster", PostMasterCopy))
  646.  
  647.                     {
  648.                         syserr("cannot parse postmaster!");
  649.                         ExitStat = EX_SOFTWARE;
  650.                         state = ESM_USRTMP;
  651.                         break;
  652.                     }
  653.                     else
  654.                     {
  655.                         syserr("cannot parse postmaster from OP!");
  656.  
  657.                         /* fake a new OP and try again */
  658.                         free((char *) PostMasterCopy);
  659.                         PostMasterCopy = newstr("postmaster");
  660.                         
  661.                         /* bad OP but return o.k. exit stat */
  662.                         ExitStat = EX_OK;
  663.                         state = ESM_POSTMASTER;
  664.                         /* is this really necessary? */
  665.                         q = e->e_errorqueue;
  666.                         break;
  667.                     }
  668.                     
  669.                     }
  670.                     alias(q, &q);
  671.                 }
  672.                 else if (parseaddr("postmaster", q, 0, '\0') == NULL)
  673.                 {
  674. d242 1
  675. a242 2
  676.                        q, state == ESM_MAIL) == 0 &&
  677.                 state == ESM_POSTMASTER)
  678. d373 1
  679. a373 3
  680.     ADDRESS *p, *q;
  681.     char *to, *cc;
  682.     int len;
  683. a395 3
  684.     /* undefine sending host & proto for error msg */
  685.     define('s', MACNULL, ee);
  686.     define('r', MACNULL, ee);
  687. d401 2
  688. a402 5
  689.  
  690.     /* put the recipients in the to: header (cc: for PostMasterCopy) */
  691.     cc = NULL;
  692.     to = buf;
  693.     for (q = returnq; q != NULL; q = q->q_next) {
  694. d404 1
  695. a404 24
  696.         if (PostMasterCopy && (strcmp(q->q_paddr, PostMasterCopy) == 0))
  697.             cc = q->q_paddr;
  698.         else {
  699.             /* Not Postmaster; already on the To: line? */
  700.             for (p = returnq; p != q; p = p->q_next)
  701.             if (strcasecmp(p->q_paddr, q->q_paddr) == 0)
  702.                 break;
  703.             if (p == q) {
  704.             /* No, add it */
  705.             *to++ = ',';
  706.             *to++ = ' ';
  707.  
  708.             len = strlen(q->q_paddr);
  709.             if (q->q_paddr[0] == '<' && q->q_paddr[len-1] == '>' &&
  710.                 q->q_paddr[1] != '@@') {
  711.                 /* Remove angle brackets; they aren't needed */
  712.                 strncpy(to, q->q_paddr+1, len-2);
  713.                 to += len-2;
  714.             } else {
  715.                 strcpy(to, q->q_paddr, len);
  716.                 to += len;
  717.             }
  718.             }
  719.         }
  720. a405 5
  721.     *to = '\0';
  722.     if (to != buf)
  723.         addheader("to", buf+2, ee);
  724.     if (cc)
  725.         addheader("cc", cc, ee);
  726. @
  727.  
  728.  
  729. 5.13.0.2
  730. log
  731. @Backed out header-only postmastercc patch as it was dying with unknown
  732. mailer error 1.  
  733. @
  734. text
  735. @a221 6
  736.  
  737.                 /* deliver a cc: to the postmaster if desired */
  738.                 if (PostMasterCopy != NULL)
  739.                     sendtolist(PostMasterCopy,
  740.                         (ADDRESS *) NULL,
  741.                         &e->e_errorqueue);
  742. d226 1
  743. a226 1
  744.                 if (parseaddr("postmaster", q, 0, '\0') == NULL)
  745. d228 32
  746. d268 2
  747. a269 1
  748.                        q, TRUE) == 0)
  749. d460 1
  750. a460 1
  751.     }
  752. @
  753.  
  754.  
  755. 5.13.0.3
  756. log
  757. @Check for room in to string before adding chars to it (from Paul Vixie).
  758. @
  759. text
  760. @a420 5
  761.             len = strlen(q->q_paddr);
  762.  
  763.             if (to+2+len+1 >= buf + sizeof buf)
  764.                 break;
  765.  
  766. d424 1
  767. @
  768.  
  769.  
  770. 5.13.0.4
  771. log
  772. @Return-Path: comp.mail.sendmail
  773. From: e07@@nikhefh.nikhef.nl (Eric Wassenaar)
  774. Date: 27 Aug 90 09:21:40 GMT
  775. Newsgroups: comp.mail.sendmail,comp.bugs.4bsd
  776. Subject: incorrect address rewriting during returntosender
  777.  
  778. Ref:    All versions of sendmail up to/including 5.64
  779.  
  780. Description:
  781.     Sendmail will rewrite 'new style' addresses in the header
  782.     lines incorrectly when returning a message to the sender,
  783.     e.g. when mailing back a return receipt or an error message.
  784.  
  785. Repeat-by:
  786.     Send a message    To: him@@hisdomain
  787.     and ask for a    Return-Receipt-To: Your Name <you@@yourdomain>
  788.  
  789.     Most probably (assuming his sendmail generates fully qualified
  790.     addresses, and can handle 'old style' addresses) this appears
  791.     in the return message as
  792.     To: Your@@hisdomain, Name@@hisdomain, <you@@yourdomain>
  793.  
  794. Analysis:
  795.     Sendmail returns a message using the sequence
  796.         sendtolist(recipient_list, ...)
  797.         returntosender(...)
  798.     The recipient(s) are parsed within sendtolist(), the 'new style'
  799.     address is recognized, and the EF_OLDSTYLE bit is cleared in the
  800.     envelope e_flags field.
  801.     The actual delivery is done within returntosender(), but this
  802.     routine switches to a temporary envelope which gets the default
  803.     e_flags with the EF_OLDSTYLE bit set.
  804.     During subsequent header rewriting, in putheader() and commaize(),
  805.     the headers are handled incorrectly, with the above result.
  806. @
  807. text
  808. @a402 2
  809.     if (!bitset(EF_OLDSTYLE, CurEnv->e_flags))
  810.         ee->e_flags &= ~EF_OLDSTYLE;
  811. @
  812.  
  813.  
  814. 5.13.0.5
  815. log
  816. @Changes from Berkeley's 5.64 to 5.65 release (main.c, savemail.c, and
  817. version.c)
  818. @
  819. text
  820. @d22 1
  821. a22 1
  822. static char sccsid[] = "@@(#)savemail.c    5.14 (Berkeley) 8/29/90";
  823. a402 1
  824.     ee->e_flags |= EF_RESPONSE;
  825. d405 1
  826. @
  827.  
  828.  
  829. 5.13.0.6
  830. log
  831. @Bruce Lilly (bruce%balilly@@sonyd1.broadcast.sony.com) provided patch to
  832. strip extraneous newlines from putline() arguments.  Fixed fencepost
  833. bug with third expand() argument.
  834. @
  835. text
  836. @d66 1
  837. a66 1
  838.     auto ADDRESS *q = NULL;
  839. d176 1
  840. a176 1
  841.             expand("\001n", buf, &buf[(sizeof(buf)-1)], e);
  842. d194 1
  843. a194 1
  844.                 while (fgets(buf, sizeof(buf), fp) != NULL &&
  845. d282 1
  846. a282 1
  847.                 expand("\001z/dead.letter", buf, &buf[(sizeof(buf)-1)], e);
  848. d315 1
  849. a315 1
  850.             putline("", fp, ProgMailer);
  851. d317 1
  852. a317 1
  853.             putline("", fp, ProgMailer);
  854. d425 1
  855. a425 1
  856.             if (to+2+len+1 > buf + sizeof buf - 1)
  857. d453 1
  858. a453 1
  859.     expand("\001n", buf, &buf[(sizeof(buf) - 1)], CurEnv);
  860. d539 2
  861. a540 2
  862.             putline("", fp, m);
  863.             putline("   ----- Unsent message follows -----", fp, m);
  864. d543 1
  865. a543 1
  866.             putline("", fp, m);
  867. d548 2
  868. a549 2
  869.             putline("", fp, m);
  870.             putline("  ----- Message header follows -----", fp, m);
  871. d556 3
  872. a558 3
  873.         putline("", fp, m);
  874.         putline("  ----- No message was collected -----", fp, m);
  875.         putline("", fp, m);
  876. @
  877.  
  878.  
  879. 5.13.0.7
  880. log
  881. @Change calls to putline() and parseaddr() to not use constant strings.
  882. Commented out tokens following #endif statements.
  883. @
  884. text
  885. @d25 3
  886. a27 3
  887. #include <sys/types.h>
  888. #include <pwd.h>
  889. #include "sendmail.h"
  890. a58 2
  891. static char    Root[] = "root";    /* for gcc */
  892. static char    PostMaster[] = "postmaster";
  893. d93 1
  894. a93 1
  895.         if (parseaddr(Root, &e->e_from, 0, '\0') == NULL)
  896. d232 1
  897. a232 1
  898.                 if (parseaddr(PostMaster, q, 0, '\0') == NULL)
  899. d330 1
  900. a330 1
  901. #ifdef LOG
  902. d333 1
  903. a333 1
  904. #endif /* LOG */
  905. d437 1
  906. a437 1
  907.                 (void) strcpy(to, q->q_paddr, len);
  908. d540 1
  909. a540 2
  910.             (void) strcpy(buf, "   ----- Unsent message follows -----");
  911.             putline(buf, fp, m);
  912. d549 1
  913. a549 2
  914.             (void) strcpy(buf, "  ----- Message header follows -----");
  915.             putline(buf, fp, m);
  916. d557 1
  917. a557 2
  918.         (void) strcpy(buf, "  ----- No message was collected -----");
  919.         putline(buf, fp, m);
  920. @
  921.  
  922.  
  923. 5.13.0.8
  924. log
  925. @Deleted #include <sys/types.h> as it's already included via sendmail.h from
  926. useful.h.  #include "sendmail.h" relocated to top of #include list.
  927. @
  928. text
  929. @d25 2
  930. a27 1
  931. #include <pwd.h>
  932. @
  933.  
  934.  
  935. 5.13.0.9
  936. log
  937. @Added static keyword to declaration of errbody().
  938. @
  939. text
  940. @d369 1
  941. a369 2
  942.     extern putheader();
  943.     static errbody();
  944. a498 1
  945. static
  946. @
  947.  
  948.  
  949. 5.13.0.10
  950. log
  951. @ANSIfied.
  952. @
  953. text
  954. @a27 6
  955. #ifdef __STDC__
  956. static void errbody(FILE *, MAILER *, ENVELOPE *);
  957. #else /* !__STDC__ */
  958. static void errbody();
  959. #endif /* __STDC__ */
  960.  
  961. a60 1
  962. void
  963. d69 1
  964. d71 1
  965. d364 1
  966. a364 1
  967.     const char *msg;
  968. d369 2
  969. d372 1
  970. d500 1
  971. a500 1
  972. static void
  973. d503 1
  974. a503 1
  975.     register MAILER *m;
  976. @
  977.  
  978.  
  979. 5.13.0.11
  980. log
  981. @Put overly long headers (> 500 bytes) at end of message body.  Adapted
  982. from Paul Vixie's patch.
  983. @
  984. text
  985. @d471 1
  986. a471 1
  987.     eatheader(ee, NULL);
  988. @
  989.  
  990.  
  991. 5.13.0.12
  992. log
  993. @strcpy() was used where strncpy was needed.
  994. @
  995. text
  996. @d441 1
  997. a441 1
  998.                 (void) strncpy(to, q->q_paddr, len);
  999. @
  1000.  
  1001.  
  1002. 5.13.0.13
  1003. log
  1004. @Added RCS ID string
  1005. @
  1006. text
  1007. @a22 1
  1008. static char  rcsid[] = "@@(#)$Id$";
  1009. @
  1010.  
  1011.  
  1012. 5.13.0.14
  1013. log
  1014. @System 5 and general improvement patches contributed by Bruce Lilly
  1015. (bruce%balilly@@broadcast.sony.com).
  1016. @
  1017. text
  1018. @d22 2
  1019. a23 2
  1020. static char sccsid[] = "@@(#)savemail.c    5.14 (Berkeley) 8/29/90    %I% local";
  1021. static char  rcsid[] = "@@(#)$Id: savemail.c,v 5.13.0.13 1991/04/05 14:55:15 paul Exp paul $";
  1022. a368 1
  1023. int
  1024. d417 2
  1025. a418 4
  1026.     for (q = returnq; q != NULL; q = q->q_next)
  1027.     {
  1028.         if (q->q_alias != NULL)
  1029.             continue;
  1030. d420 26
  1031. a445 32
  1032.             cc = q->q_paddr;
  1033.         else
  1034.         {
  1035.             /* Not Postmaster; already on the To: line? */
  1036.             for (p = returnq; p != q; p = p->q_next)
  1037.                 if (strcasecmp(p->q_paddr, q->q_paddr) == 0)
  1038.                     break;
  1039.             if (p == q)
  1040.             {
  1041.                 /* No, add it */
  1042.                 len = strlen(q->q_paddr);
  1043.                 if (to+2+len+1 > buf + sizeof buf - 1)
  1044.                     break;
  1045.                 *to++ = ',';
  1046.                 *to++ = ' ';
  1047.                 if (q->q_paddr[0] == '<' &&
  1048.                     q->q_paddr[len-1] == '>' &&
  1049.                     q->q_paddr[1] != '@@')
  1050.                 {
  1051.                     /*
  1052.                      * Remove angle brackets;
  1053.                      * they aren't needed.
  1054.                      */
  1055.                     (void) strncpy(to, q->q_paddr+1, len-2);
  1056.                     to += len-2;
  1057.                 }
  1058.                 else
  1059.                 {
  1060.                     (void) strncpy(to, q->q_paddr, len);
  1061.                     to += len;
  1062.                 }
  1063.             }
  1064. d450 1
  1065. a450 1
  1066.         addheader("to", buf+2, ee);
  1067. d452 1
  1068. a452 1
  1069.         addheader("cc", cc, ee);
  1070. @
  1071.  
  1072.  
  1073. 5.13.0.15
  1074. log
  1075. @Editted sccsid string.
  1076. @
  1077. text
  1078. @d22 2
  1079. a23 2
  1080. static char sccsid[] = "@@(#)savemail.c    5.14 (Berkeley) 8/29/90";
  1081. static char  rcsid[] = "@@(#)$Id: savemail.c,v 5.13.0.14 1991/05/18 18:18:55 paul Exp paul $";
  1082. @
  1083.